#ifndef _STACK_H_
#define _STACK_H_

#include "Exceptions.h"
#include <cassert>

namespace DataStructuresWet1
{

template <class DataT>
class Stack
{
public:
	Stack(int maxSize);
	Stack(Stack<DataT>& other);
	~Stack();
	void Push(DataT* data);
	DataT* Pop();
	DataT* Peek();
	int Size();
	int MaxSize();
protected:
	DataT** arr;
	int maxSize;
	int pos;
};

template <class DataT>
Stack<DataT>::Stack(int maxSize) : maxSize(maxSize), pos(-1), arr(new DataT*[maxSize]){}

template <class DataT>
Stack<DataT>::Stack(Stack<DataT>& other) : maxSize(other.MaxSize), pos(other.pos)
{
	memcpy(this->arr, other.arr, maxSize * sizeof(DataT*));
}

template <class DataT>
Stack<DataT>::~Stack()
{
	delete arr;
}

template <class DataT>
void Stack<DataT>::Push(DataT* data)
{
	if (pos >= maxSize - 1)
	{
		throw FailureException();
	}
	arr[pos++] = data;
}

template <class DataT>
DataT* Stack<DataT>::Pop()
{
	assert(pos>=-1);
	if (pos == -1)
	{
		return NULL;
	}
	return arr[pos--];
}

template <class DataT>
DataT* Stack<DataT>::Peek()
{
	if (pos == -1)
	{
		return NULL;
	}
	return arr[pos];
}

template <class DataT>
int Stack<DataT>::Size()
{
	return pos+1;
}

template <class DataT>
int Stack<DataT>::MaxSize()
{
	return maxSize;
}

} //DataStructuresWet1

#endif //_STACK_H_
